import axios from "axios";
import qs from "qs";
import { useUserStoreHook } from "@/store/modules/user.store";
import { ResultEnum } from "@/enums/api/result.enum";
import { getAccessToken } from "@/utils/auth";
import router from "@/router";
import { ElNotification } from 'element-plus'

// 创建 axios 实例
const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
  headers: { "Content-Type": "application/json;charset=utf-8" },
  paramsSerializer: (params) => qs.stringify(params),
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // console.log('[Axios Request] url:', config.url, 'headers:', config.headers, 'params/data:', config.params || config.data);
    const accessToken = getAccessToken();
    // 如果 Authorization 设置为 no-auth，则不携带 Token
    if (config.headers.Authorization !== "no-auth" && accessToken) {
      config.headers.Authorization = `Bearer ${accessToken}`;
    } else {
      delete config.headers.Authorization;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器
service.interceptors.response.use(
  async (response) => {
    const { config } = response;
    // console.log('原始响应:', response); // 新增日志
    // 如果响应是二进制流，则直接返回，用于下载文件、Excel 导出等
    if (response.config.responseType === "blob") {
      return response;
    }
    const { code, msg , data} = response.data;
    // 下面两个输出的结构是一样的
    // console.log("---------------response.data.data",response.data.data)
    console.log("---------------data",data)
    console.log("---------------msg",msg)
    console.log("---------------code",code)
    if (code === ResultEnum.SUCCESS) {                      //200
      //正常解析结果
      return data; 
    }else if (code === ResultEnum.ACCESS_TOKEN_INVALID) {   //10001
      // 访问 Token 过期，刷新 Token 
      return handleTokenRefresh(config);
    } else if (code === ResultEnum.REFRESH_TOKEN_INVALID) { //10002
      // 刷新 Token 过期，跳转登录页
      await handleSessionExpired();
      return Promise.reject(new Error(msg || "Error"));
    } else{
      ElNotification.error({                                //9001
        title: '失败',
        message: msg || '系统出错',
        type: 'error',
        duration: 2000,
      })
      return Promise.reject(new Error(msg || "Error"));
    }
  },
  async (error) => {
    console.error("request error", error); // for debug
    const { config, response } = error;
    if (response) {
      const { code, msg } = response.data;
      if (code === ResultEnum.ACCESS_TOKEN_INVALID) {
        // Token 过期，刷新 Token
        return handleTokenRefresh(config);
      } else if (code === ResultEnum.REFRESH_TOKEN_INVALID) {
        // 刷新 Token 过期，跳转登录页
        await handleSessionExpired();
        return Promise.reject(new Error(msg || "Error"));
      } else {
        ElNotification.error({
            title: '失败',
            message: msg || "系统出错",
            type: 'success',
            duration: 2000,
        })
      }
    }
    return Promise.reject(error.message);
  }
);


export default service;

// 是否正在刷新标识，避免重复刷新
let isRefreshing = false;
// 因 Token 过期导致的请求等待队列
const waitingQueue = [];

// 刷新 Token 处理
async function handleTokenRefresh(config) {
  return new Promise((resolve) => {
    // 封装需要重试的请求
    const retryRequest = () => {
      config.headers.Authorization = `Bearer ${getAccessToken()}`;
      resolve(service(config));
    };
    waitingQueue.push(retryRequest);
    if (!isRefreshing) {
      isRefreshing = true;
      useUserStoreHook()
        .refreshToken()
        .then(() => {
          // 依次重试队列中所有请求, 重试后清空队列
          waitingQueue.forEach((callback) => callback());
          waitingQueue.length = 0;
        })
        .catch(async (error) => {
          console.error("handleTokenRefresh error", error);
          // 刷新 Token 失败，跳转登录页
          await handleSessionExpired();
        })
        .finally(() => {
          isRefreshing = false;
        });
    }
  });
}

// 处理会话过期
async function handleSessionExpired() {
  ElNotification({
    title: "提示",
    message: "您的会话已过期，请重新登录",
    type: "info",
  });
  await useUserStoreHook().clearSessionAndCache();
  router.push("/login");
} 